package net.maku.generator.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.maku.generator.common.exception.ServerException;
import net.maku.generator.common.page.PageResult;
import net.maku.generator.common.service.impl.BaseServiceImpl;
import net.maku.generator.dao.TemplateGroupDao;
import net.maku.generator.domain.entity.ProjectEntity;
import net.maku.generator.domain.entity.TemplateEntity;
import net.maku.generator.domain.entity.TemplateGroupEntity;
import net.maku.generator.domain.query.Query;
import net.maku.generator.enums.TemplateGroupTypeEnum;
import net.maku.generator.service.ProjectService;
import net.maku.generator.service.TemplateGroupService;
import net.maku.generator.service.TemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Date;
import java.util.List;


@Service
public class TemplateGroupServiceImpl extends BaseServiceImpl<TemplateGroupDao, TemplateGroupEntity> implements TemplateGroupService {

    @Autowired
    private TemplateGroupDao templateGroupDao;

    @Autowired
    private TemplateService templateService;

    @Autowired
    private ProjectService projectService;

    @Override
    public PageResult<TemplateGroupEntity> page(Query query) {
        IPage<TemplateGroupEntity> pageObj = new Page<>(query.getPage(), query.getLimit());
        LambdaQueryWrapper<TemplateGroupEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StrUtil.isNotBlank(query.getGroupName()), TemplateGroupEntity::getGroupName, query.getGroupName());
        wrapper.orderByDesc(TemplateGroupEntity::getCreateTime);
        // 根据需求添加查询条件（如groupName等）
        IPage<TemplateGroupEntity> result = templateGroupDao.selectPage(pageObj, wrapper);
        return new PageResult<>(result.getRecords(), result.getTotal());
    }

    @Override
    public TemplateGroupEntity getById(Long id) {
        TemplateGroupEntity templateGroup = templateGroupDao.selectById(id);
        Query query = new Query();
        query.setTemplateGroupId(id);
        List<TemplateEntity> templateList = templateService.list(query);
        templateGroup.setTemplateList(templateList);
        return templateGroup;
    }

    @Override
    public List<TemplateGroupEntity> list(String groupName, TemplateGroupTypeEnum type) {
        LambdaQueryWrapper<TemplateGroupEntity> wrapper = Wrappers.lambdaQuery(TemplateGroupEntity.class);
        wrapper.like(StrUtil.isNotBlank(groupName), TemplateGroupEntity::getGroupName, groupName);
        wrapper.eq(type != null, TemplateGroupEntity::getType, type);
        wrapper.orderByDesc(TemplateGroupEntity::getCreateTime);
        return templateGroupDao.selectList(wrapper);
    }

    @Override
    public void updateDataById(TemplateGroupEntity templateGroup) {
        templateGroupDao.updateById(templateGroup);
    }

    @Override
    public void saveData(TemplateGroupEntity templateGroup) {
        templateGroup.setCreateTime(new Date());
        templateGroupDao.insert(templateGroup);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void copy(TemplateGroupEntity templateGroup) {
        TemplateGroupEntity oldTemplateGroup = getById(templateGroup.getId());
        templateGroup.setId(null);
        templateGroup.setCreateTime(new Date());
        templateGroupDao.insert(templateGroup);

        Long newTemplateGroupId = templateGroup.getId();
        List<TemplateEntity> templateList = oldTemplateGroup.getTemplateList();
        if (CollUtil.isNotEmpty(templateList)) {
            templateList.forEach(template -> {
                template.setId(null);
                template.setTemplateGroupId(newTemplateGroupId);
                template.setCreateTime(new Date());
                templateService.add(template);
            });
        }
    }

    @Override
    public void importTemplateGroup(MultipartFile file) throws Exception {
        String data = IoUtil.read(file.getInputStream(), CharsetUtil.CHARSET_UTF_8);
        List<TemplateGroupEntity> list = JSONUtil.toList(data, TemplateGroupEntity.class);
        list.forEach(templateGroup -> {
            templateGroup.setId(null);
            templateGroup.setCreateTime(new Date());
            templateGroupDao.insert(templateGroup);

            if (CollUtil.isNotEmpty(templateGroup.getTemplateList())) {
                templateGroup.getTemplateList().forEach(template -> {
                    template.setId(null);
                    template.setTemplateGroupId(templateGroup.getId());
                    template.setCreateTime(new Date());
                    templateService.add(template);
                });
            }
        });
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void deleteData(List<Long> idList) {
        boolean exists = projectService.exists(Wrappers.<ProjectEntity>lambdaQuery().in(ProjectEntity::getProjectTemplateGroupId, idList));
        if (exists) {
            throw new ServerException("模板组已被项目引用，不能删除");
        }
        exists = projectService.exists(Wrappers.<ProjectEntity>lambdaQuery().in(ProjectEntity::getTableTemplateGroupId, idList));
        if (exists) {
            throw new ServerException("模板组已被项目引用，不能删除");
        }
        templateGroupDao.deleteBatchIds(idList);
        templateService.deleteByGroupIds(idList);
    }

}
